﻿using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using FileSynchronizer.DataAccess;

namespace FileSynchronizer.Objects
{
    public enum State
    {
        Initializing,
        AutoSync,
        RunMinimized,
        SyncFolderPair,
        SyncAllFolderPairs,
        Idle
    }

    //---------------------------------------------------------------------------------------------------------------------------------------
    // Code based upon the State Pattern, as described by the GOF
    //
    // http://en.wikipedia.org/wiki/State_pattern and http://en.wikipedia.org/wiki/Talk:State_pattern#Disputed
    //
    // This is the Context Object
    //
    //---------------------------------------------------------------------------------------------------------------------------------------

    public class ProgramContext
    {
        #region Private variables
        //---------------------------------------------------------------------------------------------------------------------------------------
        private ProgramState myProgramState;
        private State myState;
        private FileSynchronizerSettings mySettings;
        //---------------------------------------------------------------------------------------------------------------------------------------
        #endregion

        #region Public variables and properties
        //---------------------------------------------------------------------------------------------------------------------------------------
        public State CurrentState
        {
            get
            {
                return myState;
            }
            set
            {
                myState = value;
            }
        }

        public FileSynchronizerSettings Settings
        {
            get
            {
                return mySettings;
            }
        }
        //---------------------------------------------------------------------------------------------------------------------------------------
        #endregion

        #region Constructors
        //---------------------------------------------------------------------------------------------------------------------------------------
        public ProgramContext()
        {
            myProgramState = new ProgramState_Initializing(this);
            myState = State.Initializing;
        }
        //---------------------------------------------------------------------------------------------------------------------------------------
        #endregion

        #region Public Methods
        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to change the state
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool ChangeState(ProgramState NewProgramState)
        {
            myProgramState = NewProgramState;
            return true;
        }

        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to Delete a FolderPair
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool DeleteFolderPair(FolderPair TheFolderPair, SyncDatabaseHelper TheSyncDatabaseHelper)
        {
            bool OperationResult = false;

            if (myProgramState != null)
            {
                OperationResult = myProgramState.DeleteFolderPair(TheFolderPair, TheSyncDatabaseHelper);
            }

            return OperationResult;
        }

        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to Synchronize a FolderPair
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool SynchronizeFolderPair(FolderPair TheFolderPair, SyncDatabaseHelper TheSyncDatabaseHelper)
        {
            bool OperationResult = false;
            string ErrorString;

            if (myProgramState != null)
            {
                if (Directory.Exists(TheFolderPair.LeftFolder) & Directory.Exists(TheFolderPair.RightFolder))
                {
                    OperationResult = myProgramState.SynchronizeFolderPair(TheFolderPair);
                }
                else
                {
                    if (!mySettings.DisableFolderWarning)
                    {
                        if (!Directory.Exists(TheFolderPair.LeftFolder))
                        {
                            ErrorString = TheFolderPair.LeftFolder;
                        }
                        else
                        {
                            ErrorString = TheFolderPair.RightFolder;
                        }
                        if (MessageBox.Show("Unable to Access '" + ErrorString + "'\r\n\r\nDo you want to remove this folderpair", "Warning", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.Yes)
                        {
                            myProgramState.DeleteFolderPair(TheFolderPair, TheSyncDatabaseHelper);
                        }
                    }
                }
            }

            return OperationResult;
        }

        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to Synchronize all FolderPairs
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool SynchronizeAllFolderPairs(IQueryable<FolderPair> TheFolderPairs)
        {
            bool OperationResult = false;

            if (TheFolderPairs != null)
            {
                OperationResult = myProgramState.SynchronizeAllFolderPairs(TheFolderPairs, null);
            }

            return OperationResult;
        }
        
        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to Load the settings
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool LoadSettings()
        {
            bool OperationResult = false;

            if (myProgramState != null)
            {
                mySettings = myProgramState.LoadSettings();
                if (mySettings != null)
                {
                    if (mySettings.RunMinimized)
                    {
                        myProgramState = new ProgramState_Minimized_Initialized(this);
                        myState = State.Initializing;
                    }
                    else
                    {
                        myProgramState = new ProgramState_Initialized(this);
                        myState = State.Initializing;
                    }
                }
            }

            return OperationResult;
        }

        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to Strore the Settings
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool SaveSettings()
        {
            mySettings.Save();
            return true;
        }

        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to check if some actions are required upon startup
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool ProcessStartup(IQueryable<FolderPair> TheFolderPairs, RunWorkerCompletedEventHandler ExternalCompletionHandler)
        {
            bool OperationResult = false;

            if (mySettings.SyncAtStartup)
            {
                if (myProgramState != null)
                {
                    OperationResult = myProgramState.SynchronizeAllFolderPairs(TheFolderPairs, ExternalCompletionHandler);
                }
            }
            else
            {
                if (myProgramState != null)
                {
                    OperationResult = myProgramState.GotoIdleState();
                    if (ExternalCompletionHandler != null)
                    {
                        ExternalCompletionHandler(this, null);

                    }
                }
            }
            return OperationResult;
        }

        //---------------------------------------------------------------------------------------------------------------------------------------
        // Called when we want to 'Un-Minimize' the ProgramState
        //---------------------------------------------------------------------------------------------------------------------------------------
        public bool RunNotMinimized()
        {
            bool OperationResult = false;

            if (myProgramState != null)
            {
                OperationResult = myProgramState.RunNotMinimized();
            }
            return OperationResult;
        }
    }
    //---------------------------------------------------------------------------------------------------------------------------------------
    #endregion
}
